﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Moq;
using PricePortalLib;
using SWT_Handin_1;

namespace TestProject1
{

    [TestFixture]
    public class FindItemTests
    {
        Item item, oldItem;
        FindItem findItem;
        List<IItem> nonEmptyList, oldList;
        List<IItem> emptyList;

        Mock<ISearchSubSupplier> ISearchSubSupplierMock = new Mock<ISearchSubSupplier>();
        Mock<IItemCache> IItemCacheMock = new Mock<IItemCache>();
        const uint cacheExpireTime = 9;

        [SetUp]
        public void setupMqs()
        {
            //Setting up item
            item = new Item();
            item.Hit = DateTime.Now;

            //Setting up oldItem
            oldItem = new Item();
            DateTime toOld = DateTime.Now.AddHours(-10);
            oldItem.Hit = toOld;

            //Setting up ItemLists
            nonEmptyList = new List<IItem> {item, oldItem};

            //Setting up oldList
            oldList = new List<IItem> {oldItem};

            //Setting emptyList
            emptyList = new List<IItem>();

            //Setting up SearchSubSupplierMock
            ISearchSubSupplierMock.Setup(foo => foo.LookUpItem(316, "Håb")).Returns(nonEmptyList);
            ISearchSubSupplierMock.Setup(foo => foo.LookUpItem(314, "Pi")).Returns(emptyList);

            //Setting up ItemCacheMock
            IItemCacheMock.Setup(foo => foo.LookUpItem(316, "Håb")).Returns(emptyList);
            IItemCacheMock.Setup(foo => foo.LookUpItem(42, "Melon")).Returns(nonEmptyList);
            IItemCacheMock.Setup(foo => foo.LookUpItem(314, "Pi")).Returns(emptyList);

            //Setting up Find Item
            findItem = new FindItem(ISearchSubSupplierMock.Object, IItemCacheMock.Object, cacheExpireTime);

        }

        //Tester hele Item, alle dens get og setter
        [Test]
        public void ItemSubSupplierGetSet()
        {
            uint value = 22;

            item.SubSupplier = value;

            Assert.AreEqual(value, item.SubSupplier);
        }

        [Test]
        public void ItemPartNumberGetSet()
        {
            ulong value = 22;

            item.PartNumber = value;

            Assert.AreEqual(value, item.PartNumber);
        }

        [Test]
        public void ItemDescriptionGetSet()
        {
            String value = "hej";

            item.Description = value;

            Assert.AreEqual(value, item.Description);
        }

        [Test]
        public void ItemHitGetSet()
        {
            DateTime value = new DateTime();

            item.Hit = value;

            Assert.AreEqual(value, item.Hit);
        }

        //Chekker om man kan finde items i local cache og trække gamle fra
        [Test]
        public void getItemsCacheItem()
        {
            Assert.AreEqual(1, findItem.LookUpItem(42, "Melon").Count);
        }

        //tjekker at gamle items bliver fjernet fra cachen
        [Test]
        public void removeOldcacheItem()
        {
            findItem.LookUpItem(42, "Melon");

            IItemCacheMock.Verify(foo => foo.RemoveItems(oldList), Times.AtLeastOnce());
        }

        //Chekker om vi kan få en tom liste, hvis item ikke findes nogen steder
        [Test]
        public void getEmptyListCacheItem()
        {
            Assert.AreEqual(0, findItem.LookUpItem(314, "Pi").Count);
        }

        //tjekker om vi kan få listen fra sub suppliers, der er ingen gamle
        [Test]
        public void getItemsSearchSubSupplier()
        {
            Assert.AreEqual(2, findItem.LookUpItem(316, "Håb").Count);
        }

        //tjekker at add bliver kaldt hvis cachen ikke havde en liste men sub supplier havde
        [Test]
        public void addToCache()
        {
            List<IItem> lookUpList = findItem.LookUpItem(316, "Håb");

            foreach (IItem i in lookUpList)
            {
                i.Hit = DateTime.Now;
            }

            IItemCacheMock.Verify(foo => foo.AddItems(lookUpList), Times.AtLeastOnce());
        }

        //tester at Hit bliver opdateret
        [Test]
        public void hitUpdate()
        {
            findItem.LookUpItem(316, "Håb");

            List<IItem> lookUpList = findItem.LookUpItem(316, "Håb");

            DateTime toOld = DateTime.Now.AddHours(-cacheExpireTime);

            foreach (IItem i in lookUpList)
            {
                Assert.True(toOld.CompareTo(i.Hit) != 1);
            }
        }
    }
}
